<template>
    <div class="container">
        <div class="container-main">
            <!-- 表单搜索区域 -->
            <el-scrollbar v-if="isShowSearchRegion" max-height="300px" class="scrollbar-height">
                <slot name="search"></slot>
            </el-scrollbar>

            <!-- 表格上方搜索向下方按钮区域 -->
            <div class="btn-box" v-if="isShowBtnRegion">
                <slot name="btn"></slot>
            </div>

            <!-- 列表区域 v-bind="xx"放在最下方，如果父组件传值可以覆盖上面定义的默认值-->
            <!-- 父组件传递的属性（通过 $attrs 或显式传递的 prop）能够覆盖子组件内部的默认设置，你应该确保 v-bind 放在最后 -->
            <el-table ref="multipleTableRef" style="width: 100%" :data="filterTableData" :border="tableBorder" :style="{
                height: tableHeight || 'auto',
                minHeight: minHeight + 'px',
            }" :row-key="(row) => row[props.rowKey]" @selection-change="onSelectionChange"
                @sort-change="sortChange" v-bind="$attrs">
                <template #empty>
                    <el-empty :image-size="emptyImgSize" description="暂无数据" />
                </template>

                <el-table-column type="selection" width="60" v-if="isSelection" :reserve-selection="true"
                    :selectable="selectableCallback" align-items="left" />

                <el-table-column type="index" label="序号" min-width="60" v-if="isIndex" :index="orderHandler"
                    align="center" />
                <el-table-column v-for="item in tableHeader" :key="item.prop" header-align="center" align="center"
                    :fixed="item.label === '操作' ? 'right' : void 0" :min-width="item.label === '操作' ? '80' : void 0"
                    v-bind="item">

                    <template #header v-if="item.slotKey?.includes('tableHeaderSearch')">
                        <el-input v-model.trim="search" size="small" :placeholder="getSearchInfo.label" />
                    </template>

                    <template #default="{ row }" v-if="item.slotKey">
                        <slot v-for="slot in item.slotKey.split(',')" :name="slot" :row="row"></slot>
                        <template v-if="item.slotKey.includes('default')">
                            <el-link type="primary" :underline="false" @click="handleEdit(row)">编辑
                            </el-link>
                            <el-popconfirm title="确定删除吗？" @confirm="handleDelete(row)">
                                <template #reference>
                                    <el-link type="danger" :underline="false">删除</el-link>
                                </template>
                            </el-popconfirm>
                        </template>
                    </template>

                    <template #default="scope" v-else>
                        <template v-if="!item.render">
                            <span>{{ scope.row[item.prop] }}</span>
                        </template>

                        <template v-else>
                            <EExand :column="item" :row="scope.row" :render="item.render" :index="scope.$index" />
                        </template>
                    </template>
                </el-table-column>
            </el-table>

            <!-- 分页区域-->
            <el-pagination v-if="paginationFlag" background :page-sizes="pageSizesArr" :current-page="pageNum"
                :page-size="pageSize" :layout="layout" :total="total" popper-class="pagination-popper"
                @size-change="handleSizeChange" @current-change="handleCurrentChange"></el-pagination>
        </div>
    </div>
</template>

<script setup lang="ts">
import { onMounted, ref, watch, toRaw, nextTick, computed } from "vue";
import { ElTable } from "element-plus";
import { useSelection } from "src/hooks/useSelection";
import EExand from "./config/EExand";
import myEmits from "./config/emits";
import myProps from "./config/props";
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
const emits = defineEmits(myEmits);
const props = defineProps(myProps);
const search = ref("");
const { selectionChange, selectedListIds } = useSelection(props.rowKey);
const sortChange = (event: any) => {
    emits('handleSort', event)
}
// 搜索过滤
const filterTableData = computed(() =>
    props.tableData?.filter(
        (data) =>
            !search.value ||
            String(data[getSearchInfo.value.prop])
                .toLowerCase()
                .includes(search.value.toLowerCase())
    )
);
// 计算那列用于展示搜索
const getSearchInfo = computed(() => {
    let searchInfo = { label: "", prop: "" };
    props.tableHeader?.find((v) => {
        if (v.searchFields) {
            searchInfo = { label: v.label, prop: v.prop };
            return true;
        }
    });
    return searchInfo;
});

// 序号根据数据长度计算
const orderHandler = (index: number) => {
    const { pageNum, pageSize } = props;
    // 第0条 * 每页条数 + 当前索引+1
    return (pageNum - 1) * pageSize + index + 1;
};

//  页数改变
const handleSizeChange = (val: number | string) =>
    emits("handleSizeChange", val);
// 当前页改变
const handleCurrentChange = (val: number | string) =>
    emits("handleCurrentChange", val);

// 编辑、删除
const handleEdit = (row: object) => emits("handleEdit", row);
const handleDelete = (row: object) => emits("handleDelete", row);
// 复选框
const onSelectionChange = (val: any) => {
    emits("selection-table-change", val)
    console.log('val === ', val.map(v => v[props.rowKey]));
    selectionChange(val);
};

// 根据父组件传递的id字符串，默认选中对应行
const toggleSelection = (rows?: any) => {
    if (props.isSelection) {
        if (rows) {
            rows.forEach((row: any) => {
                const idsArr = props.selectionIds?.split(",");
                if (idsArr?.includes(row[props.rowKey].toString())) {
                    //重要
                    nextTick(() =>
                        multipleTableRef.value?.toggleRowSelection(row, true)
                    );
                }
            });
        } else {
            multipleTableRef.value!.clearSelection();
        }
    }
};
// 返回值用来决定这一行的 CheckBox 是否可以勾选
const selectableCallback = (row: any) => {
    const idsArr = props.selectionIds?.split(",");
    if (props.isDisableSelection && idsArr?.includes(row[props.rowKey].toString()))
        return false;
    return true;
};
watch(
    () => props.tableData,
    (newV) => {
        if (props.selectionIds) {
            // console.log('🤺🤺  selectionIds🚀 ==>:',JSON.stringify(newV), props.selectionIds);
            // console.log('🤺🤺  newV ==>:', newV);
            toggleSelection(toRaw(newV));
        }
    },
    {
        immediate: true,
        deep: true
    }
);

// 搜索区域高度及默认值
const Height = ref();
// 减去搜索区域高度后的table，不能有默认值不然会出现滚动条
const excludeSearchAreaAfterTableHeight = ref();
const minHeight = 100; // 最小高度值

// 获取表格高度-动态计算搜索框高度（onMounted、resize，208是已知的面包屑tebView高度）
const updateHeight = () => {
    let wrapEl = document.querySelector(".scrollbar-height");
    if (!wrapEl) return;
    Height.value = wrapEl.scrollHeight;
    if (props.isShowSearchRegion) {
        const calculatedHeight = `calc(100vh - ${200 + Height.value}px)`;
        // 确保元素的高度不会小于一个最小值
        excludeSearchAreaAfterTableHeight.value = `max(${minHeight}px, ${calculatedHeight})`;
    }
};

onMounted(() => {
    // 表格下拉动画
    const tableContainer = document.querySelectorAll<HTMLElement>(".container");
    setTimeout(() => {
        tableContainer.forEach((item) => {
            if (item) item.style.transform = "translateY(0)";
        });
        updateHeight();
    }, 800);
});
// 清空选中数据列表
const clearSelection = () => multipleTableRef.value!.clearSelection();
window.addEventListener("resize", updateHeight);
defineExpose({
    toggleSelection,
    clearSelection,
    selectedListIds
});
</script>

<style scoped lang="scss">
.container {
    padding: 15px;
    // transform: translateY(-100%);
    // transition: transform 0.4s ease-in-out;
    background-color: #f8f8f8;

    &-main {
        position: relative;
        padding: 15px;
        background-color: #fff;
        border: 1px solid #e6e6e6;
        border-radius: 5px;

        &:hover {
            box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
        }

        // transition: box-shadow 0.3s ease-in-out;

        .scrollbar-height {
            min-height: 100px;
        }

        .btn-box {
            display: flex;
            justify-content: flex-end;
            align-items: center;
            min-height: 50px;
        }

        .el-pagination {
            display: flex;
            align-items: center;
            justify-content: flex-end;
            margin-top: 20px;
        }
    }
}

// 穿透父组件
:deep(.el-link) {
    padding-left: 10px;
}

:deep(.el-table tbody .cell) {
    // 用户在表格内填写内容时有换行，在展示表格时将换行体现出来
    white-space: break-spaces;
    padding-top: 10px;
    padding-bottom: 10px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

:deep(.el-popper.is-dark) {
    max-width: 700px !important;
    word-break: break-all;
}

:deep(.el-table th.el-table__cell) {
    background-color: #f8f8f9 !important;
}

// :deep(.el-table__inner-wrapper) {
//     min-height: 200px !important;
// }</style>
